home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / zope / interface / advice.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  5.1 KB  |  145 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. """Class advice.
  5.  
  6. This module was adapted from 'protocols.advice', part of the Python
  7. Enterprise Application Kit (PEAK).  Please notify the PEAK authors
  8. (pje@telecommunity.com and tsarna@sarna.org) if bugs are found or
  9. Zope-specific changes are required, so that the PEAK version of this module
  10. can be kept in sync.
  11.  
  12. PEAK is a Python application framework that interoperates with (but does
  13. not require) Zope 3 and Twisted.  It provides tools for manipulating UML
  14. models, object-relational persistence, aspect-oriented programming, and more.
  15. Visit the PEAK home page at http://peak.telecommunity.com for more information.
  16.  
  17. $Id: advice.py 25177 2004-06-02 13:17:31Z jim $
  18. """
  19. from types import ClassType, FunctionType
  20. import sys
  21.  
  22. def getFrameInfo(frame):
  23.     '''Return (kind,module,locals,globals) for a frame
  24.  
  25.     \'kind\' is one of "exec", "module", "class", "function call", or "unknown".
  26.     '''
  27.     f_locals = frame.f_locals
  28.     f_globals = frame.f_globals
  29.     sameNamespace = f_locals is f_globals
  30.     hasModule = '__module__' in f_locals
  31.     hasName = '__name__' in f_globals
  32.     if hasModule:
  33.         pass
  34.     sameName = hasName
  35.     if sameName:
  36.         pass
  37.     sameName = f_globals['__name__'] == f_locals['__module__']
  38.     if not hasName or sys.modules.get(f_globals['__name__']):
  39.         pass
  40.     module = None
  41.     if module:
  42.         pass
  43.     namespaceIsModule = module.__dict__ is f_globals
  44.     if not namespaceIsModule:
  45.         kind = 'exec'
  46.     elif sameNamespace and not hasModule:
  47.         kind = 'module'
  48.     elif sameName and not sameNamespace:
  49.         kind = 'class'
  50.     elif not sameNamespace:
  51.         kind = 'function call'
  52.     else:
  53.         kind = 'unknown'
  54.     return (kind, module, f_locals, f_globals)
  55.  
  56.  
  57. def addClassAdvisor(callback, depth = 2):
  58.     '''Set up \'callback\' to be passed the containing class upon creation
  59.  
  60.     This function is designed to be called by an "advising" function executed
  61.     in a class suite.  The "advising" function supplies a callback that it
  62.     wishes to have executed when the containing class is created.  The
  63.     callback will be given one argument: the newly created containing class.
  64.     The return value of the callback will be used in place of the class, so
  65.     the callback should return the input if it does not wish to replace the
  66.     class.
  67.  
  68.     The optional \'depth\' argument to this function determines the number of
  69.     frames between this function and the targeted class suite.  \'depth\'
  70.     defaults to 2, since this skips this function\'s frame and one calling
  71.     function frame.  If you use this function from a function called directly
  72.     in the class suite, the default will be correct, otherwise you will need
  73.     to determine the correct depth yourself.
  74.  
  75.     This function works by installing a special class factory function in
  76.     place of the \'__metaclass__\' of the containing class.  Therefore, only
  77.     callbacks *after* the last \'__metaclass__\' assignment in the containing
  78.     class will be executed.  Be sure that classes using "advising" functions
  79.     declare any \'__metaclass__\' *first*, to ensure all callbacks are run.'''
  80.     frame = sys._getframe(depth)
  81.     (kind, module, caller_locals, caller_globals) = getFrameInfo(frame)
  82.     previousMetaclass = caller_locals.get('__metaclass__')
  83.     defaultMetaclass = caller_globals.get('__metaclass__', ClassType)
  84.     
  85.     def advise(name, bases, cdict):
  86.         if '__metaclass__' in cdict:
  87.             del cdict['__metaclass__']
  88.         
  89.         if previousMetaclass is None:
  90.             if bases:
  91.                 meta = determineMetaclass(bases)
  92.             else:
  93.                 meta = defaultMetaclass
  94.         elif isClassAdvisor(previousMetaclass):
  95.             meta = previousMetaclass
  96.         else:
  97.             meta = determineMetaclass(bases, previousMetaclass)
  98.         newClass = meta(name, bases, cdict)
  99.         return callback(newClass)
  100.  
  101.     advise.previousMetaclass = previousMetaclass
  102.     advise.callback = callback
  103.     caller_locals['__metaclass__'] = advise
  104.  
  105.  
  106. def isClassAdvisor(ob):
  107.     """True if 'ob' is a class advisor function"""
  108.     if isinstance(ob, FunctionType):
  109.         pass
  110.     return hasattr(ob, 'previousMetaclass')
  111.  
  112.  
  113. def determineMetaclass(bases, explicit_mc = None):
  114.     '''Determine metaclass from 1+ bases and optional explicit __metaclass__'''
  115.     meta = [ getattr(b, '__class__', type(b)) for b in bases ]
  116.     if len(meta) == 1:
  117.         return meta[0]
  118.     
  119.     candidates = minimalBases(meta)
  120.     if not candidates:
  121.         return ClassType
  122.     elif len(candidates) > 1:
  123.         raise TypeError('Incompatible metatypes', bases)
  124.     
  125.     return candidates[0]
  126.  
  127.  
  128. def minimalBases(classes):
  129.     '''Reduce a list of base classes to its ordered minimum equivalent'''
  130.     classes = _[1]
  131.     candidates = []
  132.     for m in classes:
  133.         for n in classes:
  134.             if issubclass(n, m) and m is not n:
  135.                 break
  136.                 continue
  137.             []
  138.         elif m in candidates:
  139.             candidates.remove(m)
  140.         
  141.         candidates.append(m)
  142.     
  143.     return candidates
  144.  
  145.